# -*- coding: utf-8 -*-

from setting import REDIS_DB_URL
from utils.const import ERRMSG
from utils.dbbase import exc_sql
import tornado.web
from tools import *
from random import randint

def get_data(sql_code, time):
    data = get_cache(sql_code)
    if not data.get('errcode') == 0:
        data = exc_sql(sql_code,fetch_type=2)
        set_cache(sql_code,data,time)
    return data

def get_cache(key_name):
    conn = redis.Redis(**REDIS_DB_URL)
    try:
        if conn.exists (key_name):
            re_value = conn.get(key_name)
            if re_value:
                return {
                    'errcode': 0,
                    'data': eval(re_value)
                }
        else:
            return dict(errcode=1)

    except redis.ConnectionError, redis.ResponseError:
        print redis.ConnectionError, redis.ResponseError
        return dict(errcode=-1)


def set_cache(key_name, re_info, cache_time):
    conn = redis.Redis(**REDIS_DB_URL)
    try:
        conn.set(name=key_name, value=re_info, ex=int(60 * cache_time))
        return True
    except redis.ConnectionError, redis.ResponseError:
        return False



def USER_KEYS(app_key):
    sql = "SELECT app_secret FROM app_key WHERE app_key = '%s'"%app_key
    data = get_data(sql, 60*60*24)
    return data

def get_cache_new(key_name):
    conn = redis.Redis(**REDIS_DB_URL)
    re_value = conn.get(key_name)
    if re_value:
        return eval(re_value)


class BaseHandler(tornado.web.RequestHandler):
    @staticmethod
    def encrypt_msg(status_code, api_key, secret_key, data):
        re_data = {
            'errcode': status_code,
            'errmsg': ERRMSG.get(status_code),
        }
        if status_code == 0:
            nonce_str = random_str(randint(20, 30))
            encrypt_msg = encrypt(api_key, secret_key, nonce_str, json.dumps(data))
            re_data['msg_signature'] = get_sha1(nonce_str, encrypt_msg)
            re_data['nonce'] = nonce_str
            re_data['encrypt_msg'] = encrypt_msg
        return re_data


    def write_json(self, **kwargs):
        return self.write(
            build_json(**kwargs)
        )


    # def security_check(self, func_args, optional_args, apply_method):
    #     compulsory_query_arguments = ['nonce', 'msg_signature']
    #     compulsory_body_arguments = ['encrypt_msg', 'api_key']
    #     query_dict = {}
    #     body_dict = {}
    #     for needed_query in compulsory_query_arguments:
    #         query_dict[needed_query] = self.get_query_argument(needed_query, None)
    #     for needed_body in compulsory_body_arguments:
    #         body_dict[needed_body] = self.get_body_argument(needed_body, None)
    #     if None in query_dict.values():
    #         return -40001, None
    #     if None in body_dict.values():
    #         return -40002, None
    #     if len(query_dict['nonce']) < 10 or len(query_dict['nonce']) > 32:
    #         return -40003, None
    #     if query_dict['msg_signature'] != get_sha1(query_dict['nonce'], body_dict['encrypt_msg'], body_dict['api_key']):
    #         return -40004, None
    #
    #     app_secret = USER_KEYS(body_dict['api_key'])
    #     if not app_secret:
    #         return -40005, None
    #
    #     ret, post_args = decrypt(body_dict['api_key'], app_secret, query_dict['nonce'],
    #                              body_dict['encrypt_msg'])
    #     if ret != 0:
    #         return ret, None
    #     if not isinstance(post_args, dict):
    #         return -40006, None
    #     if not set(post_args.keys()) >= set(func_args.values()) or \
    #             not set(post_args.keys()) <= set(func_args.values()) | set(optional_args.values()):
    #         print post_args.keys(), func_args.values()
    #         return -40007, None
    #     for each_key, each_value in func_args.items():
    #         if each_key != each_value:
    #             post_args[each_key] = post_args.pop(each_value)
    #
    #     post_args['SECRET_KEY'] = app_secret
    #     post_args['API_KEY'] = body_dict['api_key']
    #     return 0, post_args
    #
    #
    # def acquire_data(self, class_object, args=None, optional_args=None,
    #                  verify_method=None, exc_method=None, args_init=True, cache=None):
    #     re_info = None
    #     is_cache_data = None
    #     status_code, args = self.security_check(
    #         args if args else {}, optional_args if optional_args else {}, exc_method
    #     )
    #     api_key, secret_key = (args.pop('API_KEY'), args.pop('SECRET_KEY')) if status_code == 0 else (None, None)
    #     key_name = u'API_CACHE_({}.{})_{}'.format(class_object.__name__, exc_method, md5(str(args)).hexdigest())
    #     if cache and status_code == 0:
    #         re_info = get_cache_new(key_name)
    #         if re_info:
    #             is_cache_data = True
    #     if not re_info and status_code == 0:
    #         is_cache_data = False
    #
    #         instanced_class = class_object(**args) if args_init else class_object()
    #         if verify_method:
    #             status_code = getattr(instanced_class, verify_method)() \
    #                 if args_init else getattr(instanced_class, verify_method)(**args)
    #         if exc_method and status_code == 0:
    #             re_info = getattr(instanced_class, exc_method)() if args_init else getattr(instanced_class, exc_method)(
    #                 **args)
    #             if re_info and cache:
    #                 set_cache(key_name, re_info, cache)
    #
    #     self.write(json.dumps(**self.encrypt_msg(status_code, api_key, secret_key, re_info if re_info else {})))
    # def security_check(self,):

    def acquire_data(self, class_object, args=None, optional_args=None, exc_method=None, cache=None):
        compulsory_query_arguments = ['apikey']
        body_dict = {}
        query_dict = {}
        is_cache_data = None #过去的是否为缓存的数据
        re_info=[]
        status_code = 0

        for needed_query in compulsory_query_arguments:
            query_dict[needed_query] = self.get_query_argument(needed_query, None)

        for key,value in args.items():
            body_dict[key] = self.get_body_argument(key, None)

        key_name = u'API_CACHE_({}.{})_{}'.format(class_object.__name__, exc_method, md5(str(args)).hexdigest())
        if cache :
            re_info = get_cache_new(key_name)
            is_cache_data=True
            if not re_info:
                re_info = getattr(class_object, exc_method)(**body_dict)
                set_cache(key_name, re_info, cache)
        else:
            re_info = getattr(class_object, exc_method)(**body_dict)
            is_cache_data=False

        data = {
            'error':0,
            'data':re_info
        }
        print body_dict,re_info,query_dict

        from QRcodecelery import api_log_sys
        api_log_sys(u'{0}.{1}'.format(class_object.__name__, exc_method), data, body_dict,query_dict['apikey'] if query_dict['apikey'] else '')

        self.write(json.dumps(data))



































